package com.netty.io.nio.groupchat;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * 模拟多人群聊，client发送数据，其他client都能收到发送的数据
 */
public class GroupchatServer {

    private final String HOST = "127.0.0.1";

    private final int PORT = 8089;

    private Selector selector;

    private ServerSocketChannel serverSocketChannel;

    public GroupchatServer() throws Exception {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(PORT));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void listen() throws IOException {

        while (true) {
            if (selector.select(1000) == 0) {//没有事件发生
                System.out.println("服务器等待1秒，无连接");
                continue;
            }

            Set<SelectionKey> selectionKeys = selector.selectedKeys();

            Iterator<SelectionKey> iterator = selectionKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();

                if (selectionKey.isAcceptable()) {
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                    System.out.println(socketChannel.getRemoteAddress() + "已经注册成功");
                }
                if (selectionKey.isReadable()) {
                    readData(selectionKey);
                }
                iterator.remove();
            }
        }


    }

    public void redirectMessage(String message, SocketChannel socketChannel) throws IOException {

        for (SelectionKey key : selector.keys()) {
            Channel channel = key.channel();

            if (channel instanceof SocketChannel && channel != socketChannel) {
                ByteBuffer wrap = ByteBuffer.wrap(message.getBytes());
                ((SocketChannel) channel).write(wrap);
            }
        }
        System.out.println("数据转发成功");
    }


    public void readData(SelectionKey selectionKey) {

        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        SocketAddress clientName = null;
        try {
            int read = socketChannel.read(byteBuffer);
            clientName = socketChannel.getRemoteAddress();
            String message = new String(byteBuffer.array(), 0, read);
            System.out.println(clientName + "发送数据" + message);
            redirectMessage(message, socketChannel);
        } catch (IOException e) {
            e.printStackTrace();
            selectionKey.cancel();
            System.out.println(clientName + "已经离线");
        }

    }

    public static void main(String[] args) throws Exception {
        GroupchatServer groupchatServer = new GroupchatServer();
        groupchatServer.listen();
    }


}
